﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Sherwood.SignOn.Server.Models.ViewModels;
using Sherwood.SignOn.Server.Models;
using Sherwood.Mvc.Localization;
using Sherwood.Mvc;
using log4net;
using Sherwood.SignOn.Server.Models.Services;
using Sherwood.SignOn.Server.Content;

namespace Sherwood.SignOn.Server.Controllers
{
    /// <summary>
    /// The UserAccountController contains actions relating to user accounts.
    /// </summary>
    public class UserAccountController : ControllerBase
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof(UserAccountController));

        //
        // GET: /UserAccount/

        public ActionResult Index()
        {
            if (!UserSessionHelper.CurrentUserSessionId.Equals(Guid.Empty))
            {
                return Redirect("~/UserAccount/EditProfile/");
            }
            else   
            {
                return Redirect("~/");
            }
        }


        /// <summary>
        /// /UserAccount/Register GET action.
        /// The purpose of this action is to display the account creation form for new users.
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public ActionResult Register()    
        {
            UserSessionHelper.EndCurrentUserSession();
            return View();
        }

        /// <summary>
        /// /UserAccount/Register POST action.
        /// The purpose of this action is to process and validate creation of a new account. Upon successful account creation
        /// users are sent an email with a verification link to the /UserAccount/Verify action.
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Register(RegisterViewModel model)
        {
            if (model != null && !string.IsNullOrEmpty(model.CultureName1))
            {
                SetCulture(model.CultureName1, model.CultureName2, model.CultureName3);
            }
            if (ModelState.IsValid)
            {
                if (model.CreateUserAccount(ModelState))
                {
                    return View("RegisterConfirmation", model);
                }
            }
            return View(model);
        }

        /// <summary>
        /// /UserAccount/EditProfile action.
        /// Allows signed on users to change their profile.
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public ActionResult EditProfile(RegisterViewModel model)
        {
            //Ensure user is signed on
            IUserSession currentSession = UserSessionHelper.GetCurrentUserSession();
            IUserAccount user = null;
            if (currentSession == null || currentSession.UserAccount == null)
            {
                return View("EditProfilePleaseSignIn",model);
            }
            else
            {
                user = currentSession.UserAccount;
                if (UserAccountHelper.IsGlobalAccount(user.UserName))
                {
                    //Global accounts may not be edited... simply ask user to sign in.
                    return View("EditProfilePleaseSignIn", model);
                }
            }

            //Set culture for views
            if (model != null && !string.IsNullOrEmpty(model.CultureName1))
            {
                SetCulture(model.CultureName1, model.CultureName2, model.CultureName3);
            }

            //Ensure model object exits
            if (model == null)
                model = new RegisterViewModel(); //create dummy object

            //Set model parameters
            model.Country = model.Country != null ? model.Country : user.Country;
            model.CultureName1 = model.CultureName1 != null ? model.CultureName1 : user.CultureName1;
            model.CultureName2 = model.CultureName2 != null ? model.CultureName2 : user.CultureName2;
            model.CultureName3 = model.CultureName3 != null ? model.CultureName3 : user.CultureName3;
            model.DateOfBirth = model.DateOfBirth != null ? model.DateOfBirth : user.DateOfBirth;
            model.Email = model.Email != null ? model.Email : (!string.IsNullOrEmpty(user.ProposedEmail) ? user.ProposedEmail : user.Email);
            model.FirstName = model.FirstName != null ? model.FirstName : user.FirstName;
            model.Gender = model.Gender != Gender.Unspecified ? model.Gender : user.Gender;
            model.LastName = model.LastName != null ? model.LastName : user.LastName;
            model.Mobile = model.Mobile != null ? model.Mobile : user.Mobile;
            model.RequestedUrl = model.RequestedUrl != null ? model.RequestedUrl : user.RequestedUrl;
            model.UserName = model.UserName != null ? model.UserName : user.UserName;

            if (Request.HttpMethod.Equals("POST", StringComparison.CurrentCulture))
            {
                ViewData["ProfileSavedMessage"] = "";
                if (model.EditUserAccount(ModelState, user.Id))
                {
                    if (model.EmailOrPasswordChanged)
                    {
                        ViewData["ProfileSavedMessage"] = Translations.EditProfileConfirmation_Message.Parameterize(model,Config.Settings) + "<br/>"
                            + Translations.EditProfile_Changed_Email_Or_Password.Parameterize(model, Config.Settings);
                    }
                    else
                    {
                        ViewData["ProfileSavedMessage"] = Translations.EditProfileConfirmation_Message.Parameterize(model, Config.Settings);
                    }
                }
            }

            if (!string.IsNullOrEmpty(currentSession.UserAccount.ProposedEmail) && !currentSession.UserAccount.ProposedEmail.Equals(currentSession.UserAccount.Email))
            {
                model.PendingEmailChangeText = Translations.EditProfile_Pending_Email_Change.Parameterize(currentSession.UserAccount, Config.Settings);
            }

            return View(model);
        }

        /// <summary>
        /// /UserAccount/Verify action.
        /// The purpose of this action is to allow users to verify their account. Upon account creation, an email is
        /// sent to the email address provided for the account. This email contains a link with a validation code which
        /// this action uses to verify the user and validate the account. Upon successful verification, the user account's
        /// VerificationStatus is set to 'Verified'.
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public ActionResult Verify(VerifyViewModel model)
        {
            if (model == null || string.IsNullOrEmpty(model.VerificationCode) || string.IsNullOrEmpty(model.UserAccountId))
            {
                return Redirect("~/");
            }
            if (model.VerifyUser(ModelState))
            {
                if (!string.IsNullOrEmpty(model.RequestedUrl))
                {
                    string url = model.RequestedUrl;
                    return Redirect(url);
                }
            }
            return View(model);
        }

        /// <summary>
        /// /UserAccount/Verify action.
        /// The purpose of this action is to allow users to verify change of email address and / or password when editing profile.
        /// If password and / or email is changed by a user when modifying their profile, an email is sent containing
        /// a verification link which is handled by this action.
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public ActionResult EditProfileVerify(VerifyViewModel model)
        {
            UserSessionHelper.EndCurrentUserSession();
            if (model == null || string.IsNullOrEmpty(model.VerificationCode) || string.IsNullOrEmpty(model.UserAccountId))
            {
                return Redirect("~/");
            }
            if (Request.RequestType.ToLower().Equals("post"))
            {
                if (model.VerifyUserProfileModification(ModelState))
                {
                    return View("EditProfileConfirmation", model);
                }
            }
            else
            {
                IUserAccount account = Data.UserAccounts.GetUserAccount(new Guid(model.UserAccountId));
                if (account != null)
                {
                    model.MessageToUser = Translations.EditProfileVerify_Message.Parameterize(this, account, Config.Settings);
                }
                else
                {
                    model.MessageToUser = Translations.EditProfileConfirmation_Verification_Failed_Message;
                    return View("EditProfileConfirmation", model);
                }
            }
            return View(model);
        }

        /// <summary>
        /// /UserAccount/ChangePassword action.
        /// The purpose of this action is to allow users to change their password. The user's identity is verified
        /// by a validation token (which should be passed as part of the request to this action) and which would 
        /// usually have been sent to the user's email account (as a link).
        /// Since the process involves validating the user, unvalidated users will automatically be validated
        /// if they are not already validated.
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public ActionResult ChangePassword(ChangePasswordViewModel model)
        {
            if (model == null || string.IsNullOrEmpty(model.VerificationCode) || string.IsNullOrEmpty(model.UserAccountId))
            {
                return Redirect("~/");
            }
            if (ModelState.IsValid)
            {
                if (model.ChangePassword(ModelState))
                {
                    return View("ChangePasswordConfirmation", model);
                }
            }
            return View(model);
        }

        /// <summary>
        /// /UserAccount/DontChangePassword action.
        /// The purpose of this action is to allow user to cancel a password change request.
        /// Since this also involves validating the user, unvalidated users will automatically be validated
        /// if they are not already validated.
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public ActionResult DontChangePassword(DontChangePasswordViewModel model)
        {
            if (ModelState.IsValid)
            {
                if (model.DontChangePassword(ModelState))
                {
                    return View(model);
                }
            }
            return View(model);
        }




        /// <summary>
        /// /UserAccount/ForgotPassword action.
        /// The purpose of this action is to allow users to request a password reset.
        /// Users are expected to enter a username or email address and if a matching account is found,
        /// an email containing a validation link to the /UserAccount/ChangePassword action is sent to the user's email address.
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public ActionResult ForgotPassword(ForgotPasswordViewModel model)
        {
            if (ModelState.IsValid)
            {
                if (model.RequestPasswordReset(ModelState))
                {
                    return View("ForgotPasswordConfirmation", model);
                }
            }
            return View(model);
        }


        /// <summary>
        /// /UserAccount/SendVerification action.
        /// This action regenerates a verification email for the specified user account.
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public ActionResult SendVerification(SendVerificationViewModel model)
        {
            model.ResendVerificationEmail(ModelState);            
            return View(model);
        }


      
    }
}
